package com.hanxiaozhang.base.service.impl;

import com.hanxiaozhang.base.dto.JobTaskDTO;
import com.hanxiaozhang.base.quartz.config.QuartzHandler;
import com.hanxiaozhang.constant.DelFlagEnum;
import com.hanxiaozhang.exception.InternalServerException;
import com.hanxiaozhang.security.CurrentUserUtil;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.hanxiaozhang.base.dao.JobTaskDao;
import com.hanxiaozhang.base.entity.JobTaskEntity;
import com.hanxiaozhang.base.service.JobTaskService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 定时任务
 *
 * @author hanxiaozhang
 * @email hanxiaozhang2018@sina.com
 * @date 2021-04-29
 * @since 1.0.0
 */
@Service
public class JobTaskServiceImpl implements JobTaskService {

    @Resource
    private JobTaskDao jobTaskDao;

    @Autowired
    private QuartzHandler quartzHandler;

    @Override
    public JobTaskEntity get(Long id) {
        return jobTaskDao.get(id);
    }

    @Override
    public List<JobTaskDTO> list(Map<String, Object> map) {
        List<JobTaskDTO> list = jobTaskDao.list(map);
        if (!list.isEmpty()) {
            list.forEach(x -> {
                x.setNextExecuteDate(quartzHandler.nextExecuteDate(x.getCronExpression()));
            });
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(JobTaskEntity jobTask) {

        jobTask.setCreateBy(CurrentUserUtil.getUserName())
                .setCreateDate(LocalDateTime.now())
                .setDelFlag(DelFlagEnum.NORMAL.getCode());
        jobTaskDao.save(jobTask);

        if (jobTask.getJobStatus() == 1) {
            try {
                Class<?> clazz = Class.forName(jobTask.getBeanClass());
                boolean start = quartzHandler.start(jobTask, clazz);
                if (!start) {
                    throw new InternalServerException("任务启动失败,任务名称:[{}]", jobTask.getJobName());
                }
            } catch (ClassNotFoundException e) {
                throw new InternalServerException("未找到任务执行类:[{}]", e.getMessage());
            }
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(JobTaskEntity jobTask) {
        jobTask.setUpdateBy(CurrentUserUtil.getUserName())
                .setUpdateDate(LocalDateTime.now());
        jobTaskDao.update(jobTask);

        if (jobTask.getJobStatus() == 0 &&
                Trigger.TriggerState.NORMAL.toString().equals(quartzHandler.getStatus(jobTask))) {
            boolean suspend = quartzHandler.suspend(jobTask);
            if (!suspend) {
                throw new InternalServerException("任务暂停失败,任务名称:[{}]", jobTask.getJobName());
            }
        }

        if (jobTask.getJobStatus() == 1 &&
                Trigger.TriggerState.NORMAL.toString().equals(quartzHandler.getStatus(jobTask))
        ) {
            boolean update = quartzHandler.update(jobTask);
            if (!update) {
                throw new InternalServerException("任务更新失败,任务名称:[{}]", jobTask.getJobName());
            }
        }

        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(Long id) {
        deleteJobTask(id);
        jobTaskDao.remove(id);
        return 1;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchRemove(Long[] ids) {
        for (Long id : ids) {
            deleteJobTask(id);
        }
        jobTaskDao.batchRemove(ids);
        return ids.length;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer jobStatus) {

        try {
            JobTaskEntity jobTaskEntity = jobTaskDao.get(id);
            if (jobStatus == 1) {
                Class<?> clazz = Class.forName(jobTaskEntity.getBeanClass());
                boolean start = quartzHandler.start(jobTaskEntity, clazz);
                if (!start) {
                    throw new InternalServerException("任务启动失败,任务名称:[{}]", jobTaskEntity.getJobName());
                }
            } else {
                boolean suspend = quartzHandler.suspend(jobTaskEntity);
                if (!suspend) {
                    throw new InternalServerException("任务暂停失败,任务名称:[{}]", jobTaskEntity.getJobName());
                }
            }
            jobTaskDao.updateStatusById(id, jobStatus);
        } catch (Exception e) {
            throw new InternalServerException("未找到任务执行类:[{}]", e.getMessage());
        }

    }


    /**
     * 删除定时任务
     *
     * @param id
     */
    private void deleteJobTask(Long id) {
        JobTaskEntity jobTask = jobTaskDao.get(id);
        if (jobTask.getJobStatus() == 1) {
            boolean delete = quartzHandler.delete(jobTask);
            if (!delete) {
                throw new InternalServerException("任务删除失败,任务名称:[{}]", jobTask.getJobName());
            }
        }
    }

}
